#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <unistd.h>
int flag = 0;
// 互斥锁
pthread_mutex_t mutex;
// 条件变量
pthread_cond_t cond;
/**
 * 改变条件的 线程
 * @param arg
 * @return
 */
void * fun1(void * arg){
    while(1){
        //加锁
        pthread_mutex_lock(&mutex);
        flag = 1;
        //解锁
        pthread_mutex_unlock(&mutex);
        //唤醒 因为条件而阻塞的线程
        pthread_cond_signal(&cond);
        printf("thread 1 change condition\n");

        sleep(2);
    }
    return NULL;
}

/**
 * 等待条件的 线程
 * @param arg
 * @return
 */
void * fun2(void * arg){
    while(1){
        //加锁
        pthread_mutex_lock(&mutex);

        //表示条件不满足
        if(flag == 0){
            //等待条件满足 会阻塞 代码操作中可能会有一次释已存在的锁，让另外的线程获取锁，等收到唤醒信号时，再申请一次锁
            pthread_cond_wait(&cond,&mutex);
        }
        printf("thread 2 run...\n");
        flag = 0;
        //解锁
        pthread_mutex_unlock(&mutex);

    }
    return NULL;
}

/**
 * 条件变量 用来等待而不是锁 本身不是锁 通常和互斥锁同时使用
 *      条件不足，阻塞线程
 *      条件满足，通知阻塞的线程开始工作
 *
 * @return
 */
int main(){
    pthread_t tid1;
    pthread_t tid2;
    int ret = -1;
    // 初始化条件变量
    ret = pthread_cond_init(&cond,NULL);
    // 初始化互斥锁
    ret = pthread_mutex_init(&mutex,NULL);
    // 创建线程
    pthread_create(&tid1,NULL,fun1,NULL);
    pthread_create(&tid2,NULL,fun2,NULL);

    // 回收线程资源
    ret = pthread_join(tid1,NULL);
    ret = pthread_join(tid2,NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);
    // 销毁条件变量
    pthread_cond_destroy(&cond);

    printf("main exit...\n");
    return 0;
}
